/**
 * 生成基本地图
 *
 *  谷歌地图参数
 *  m：路线图
 *  t：地形图
 *  p：带标签的地形图
 *  r: skeleton map dark
 *  s：卫星图
 *  y：带标签的卫星图
 *  h：标签层（路名、地名等）
 *
 *  本应用所用的地图投影为 EPSG:4326，对应的坐标就是普通的经纬度
 * Created by kedong on 2017/7/14 0014.
 */

$(function () {
    var lastZoom = DB.getLastZoom() || '';
    var lastCenter = DB.getLastCenter() || '';
    try {
        if (!!lastCenter) {
            lastCenter = JSON.parse(lastCenter);
            if (isNaN(lastCenter[0]) || isNaN(lastCenter[1])) {
                lastCenter = false;
            }
        }
    } catch (e) {
        console.error(e);
        lastCenter = false;
    }
    var view = new ol.View({
        center: !!lastCenter ? lastCenter : [114.28, 30.55],
        projection: 'EPSG:4326',
        zoom: !isNaN(lastZoom) && lastZoom >= 4 && lastZoom <= 20 ? lastZoom : 9,
        minZoom: 4,
        maxZoom: 20
    });

    var map = new ol.Map({
        target: 'map',
        controls: ol.control.defaults({
            // 隐藏缩放按钮
            zoom: true
        }).extend([
            new ol.control.ZoomSlider()
        ]),
        // 设置默认的交互行为
        interactions: ol.interaction.defaults({
            // 禁用双击放大
            doubleClickZoom: false,
            // 禁用旋转
            altShiftDragRotate: false,
            pinchRotate: false
        }),
        layers: [
            new ol.layer.Group({
                'title': '卫星图',
                layers: [
                    new ol.layer.Tile({
                        title: '卫星图(google)',
                        type: 'base',
                        visible: true,
                        isGcj02: true,
                        source: new ol.source.XYZ({
                            url: 'http://mt2.google.cn/vt/lyrs=y@258000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Ga'
                        })
                    })
                ]
            }),
            new ol.layer.Group({
                'title': '地形图',
                layers: [
                    new ol.layer.Tile({
                        title: '地形图(google)',
                        type: 'base',
                        visible: true,
                        isGcj02: true,
                        source: new ol.source.XYZ({
                            url: 'http://mt2.google.cn/vt/lyrs=p@258000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Ga'
                        })
                    }),
                    new ol.layer.Tile({
                        title: '等高图',
                        type: 'base',
                        visible: true,
                        source: new ol.source.XYZ({
                            url: 'http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png'
                        })
                    })
                ]
            }),
            new ol.layer.Group({
                'title': '平面图',
                layers: [
                    new ol.layer.Tile({
                        title: '二维地图(google)',
                        type: 'base',
                        visible: true,
                        isGcj02: true,
                        source: new ol.source.XYZ({
                            url: 'http://mt2.google.cn/vt/lyrs=m@258000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Ga'
                        })
                    }),
                    new ol.layer.Tile({
                        title: 'OSM',
                        type: 'base',
                        visible: true,
                        source: new ol.source.OSM()
                    }),
                    new ol.layer.Tile({
                        title: '高德地图',
                        type: 'base',
                        visible: true,
                        isGcj02: true,
                        source: new ol.source.XYZ({
                            url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
                        })
                    })
                ]
            })
        ],
        view: view
    });

    var layers = getLayers();
    for (var i = 0; i < layers.length; i++) {
        var layer = layers[i];
        layer.on('change:visible', function (e) {

            var oldValue = e.oldValue;
            if (oldValue)
                return;

            console.log(e);
            var target_layer = e.target;
            var allFeatures = getAllFeatures();
            gpsConvert(target_layer, allFeatures);
        })
    }


    view.on('change:center', function (e) {
        var center = view.getCenter();
        // 保存当前视图中心坐标
        DB.setLastCenter(JSON.stringify(center));
    });

    view.on('change:resolution', function (e) {
        // 保存当前缩放级别
        DB.setLastZoom(view.getZoom());
    });

// 绘制图层所有的要素集合
    var features = new ol.Collection();
// 绘制图层
    var featureOverlay = new ol.layer.Vector({
        source: new ol.source.Vector({features: features}),
        style: styleFunction
    });
//设置绘制图层不受图层管理器控制
    featureOverlay.setMap(map);

// 绘制图层所有的要素集合
    var searchFeatures = new ol.Collection();
// 搜索图层
    var searchOverlay = new ol.layer.Vector({
        source: new ol.source.Vector({features: searchFeatures}),
        style: styleFunction
    });
//设置绘制图层不受图层管理器控制
    searchOverlay.setMap(map);

//用户轨迹要素集合
    var userPathFeatures = new ol.Collection();
    /**
     * 用户轨迹图层
     * @type {ol.layer.Vector}
     */
    var userPathOverlay = new ol.layer.Vector({
        source: new ol.source.Vector({features: userPathFeatures}),
        style: styleFunction
    });
    userPathOverlay.setMap(map);

    features.on("change:length", function (e) {
        if (features.getLength() > 0) {
            // 保存到缓存
            $.publish("features:save");
            // 设置保存按钮可用
            $.publish("save:on");
            selectOn();
        } else {
            // 设置保存按钮不可用
            $.publish("save:off");
        }

    });

    /**
     * 检查select interaction
     */
    function selectOn() {
        /**
         * 检查select interaction 是否已经添加到map中，
         * 只有当select interaction 添加到map中时，map中的要素才能被选中，否则无法选中要素进行编辑
         */
        var interactions = map.getInteractions();
        var interactionArray = interactions.getArray();

        var flag = false;
        for (var i = 0; i < interactionArray.length; i++) {
            var interaction = interactionArray[i];
            if(interaction instanceof ol.interaction.Select){
                console.log('select interaction 已添加到map中，可以开始选择图层要素');
                flag = true;
                break;
            }
        }

        if(!flag){
            $.publish("select:on");
        }
    }

    /**
     * 获取所有图层
     * @returns {Array}
     */
    function getLayers() {
        var allLayers = [];
        var groups = map.getLayers().getArray();
        for (var j = 0; j < groups.length; j++) {
            var layers = groups[j].getLayers().getArray();
            for (var i = 0; i < layers.length; i++) {
                allLayers.push(layers[i])
            }
        }
        return allLayers;
    }

    /**
     * 获取图层上所有的要素
     * @returns {Array}
     */
    function getAllFeatures() {
        var allFeatures = [];
        var users = userPathFeatures.getArray();
        for (var i = 0; i < users.length; i++) {
            allFeatures.push(users[i]);
        }
        var search = searchFeatures.getArray();
        for (var i = 0; i < search.length; i++) {
            allFeatures.push(search[i]);
        }
        var draw = features.getArray();
        for (var i = 0; i < draw.length; i++) {
            allFeatures.push(draw[i]);
        }
        return allFeatures;
    }

    /**
     * 更新轨迹的文字样式
     * @param feature
     */
    function updateContentStyle(feature) {
        try {
            console.log('更新轨迹的文字样式');
            var geometry = feature.getGeometry();
            if (geometry == null) {
                return;
            }
            var style = feature.getStyle() || new ol.style.Style();
            var textStyle = style.getText() || new ol.style.Text();

            var fontSize = feature.get('fontSize');
            var fontColor = feature.get('fontColor');
            var name = feature.get('name') || '';

            textStyle.setText(name);
            if (fontSize) {
                textStyle.setFont(fontSize + 'px sans-serif');
            }
            if (fontColor) {
                textStyle.setFill(new ol.style.Fill({
                    color: fontColor
                }))
            }
            textStyle.setStroke(new ol.style.Stroke({
                color: '#c5e7ff',
                width: 3
            }));

            style.setText(textStyle);
            feature.setStyle(style);
        } catch (e) {
            console.log(e);
        }
    }

    /**
     * 更新轨迹样式
     * @param feature
     */
    function updateFeatureStyle(feature) {
        try {
            console.log('更新轨迹样式');
            var geometry = feature.getGeometry();
            if (geometry == null) {
                return;
            }
            var type = geometry.getType();
            var style = feature.getStyle() || new ol.style.Style();
            var strokeStyle = style.getStroke() || new ol.style.Stroke();
            var iconStyle;

            switch (type) {
                case 'Point':
                    // 点
                    var pointType = feature.get('type'), iconSrc = null;
                    switch (pointType) {
                        case '1':
                            // 警告点
                            iconSrc = '/static/images/map/warning.png';
                            break;
                        case '2':
                            // 安全点
                            iconSrc = '/static/images/map/safe.png';
                            break;
                        case '3':
                            // 兴趣点
                            iconSrc = '/static/images/map/like.png';
                            break;
                        case '4':
                            // 休息点
                            iconSrc = '/static/images/map/rest.png';
                            break;
                        default:
                            iconSrc = '/static/images/map/marker-blue.png';
                            break;
                    }
                    iconStyle = new ol.style.Icon({
                        anchor: [0.5, 1],
                        scale: 1,
                        src: ctx + iconSrc
                    });
                    break;
                case 'MultiLineString':
                    //多线
                    var lineWidth = feature.get('lineWidth') || 3;
                    var lineColor = feature.get('lineColor');
                    var lineType = feature.get('lineType');
                    if (lineColor) {
                        strokeStyle.setColor(lineColor);
                    }
                    if (lineWidth) {
                        strokeStyle.setWidth(lineWidth);
                    }
                    if (lineType == 2) {
                        // 虚线
                        strokeStyle.setLineDash([15]);
                    } else if (lineType == 1) {
                        // 实线
                        strokeStyle.setLineDash([0]);
                    }
                    break;
                case 'Polygon':
                    // 面
                    break;
            }

            style.setStroke(strokeStyle);
            style.setImage(iconStyle);
            feature.setStyle(style);
        } catch (e) {
            console.log(e);
        }
    }


    /**
     * 添加要素到主图层
     * @param features
     * @param type 1:用户轨迹；2:系统轨迹
     */
    function addFeatures(features, type) {
        // 加载样式
        for (var i = 0; i < features.length; i++) {
            updateFeatureStyle(features[i]);
            updateContentStyle(features[i]);
            // 设置图层编号
            features[i].set('overlay', 'featureOverlay');
            if (type == 1) {
                features[i].set("gpsType", 1);
            }
        }
        var layer = getCurrentLayer();
        gpsConvert(layer, features);
        featureOverlay.getSource().addFeatures(features);
    }

    /**
     * 添加要素到搜索图层
     * @param features
     */
    function addFeaturesToSearchOverlay(features) {
        for (var i = 0; i < features.length; i++) {
            // 设置图层编号
            features[i].set('overlay', 'searchOverlay');
        }
        var layer = getCurrentLayer();
        gpsConvert(layer, features);
        searchOverlay.getSource().addFeatures(features);
    }

    /**
     * 删除要素
     * @param features
     */
    function removeFeatures(features) {
        if (!features)
            return;

        if (isArray(features)) {
            for (var i = 0; i < features.length; i++) {
                removeFeature(features[i]);
            }
        } else {
            removeFeature(features);
        }
    }

    function removeFeature(feature) {
        if (!feature)
            return;
        var overlay = feature.get('overlay');
        OverlayMap[overlay].getSource().removeFeature(feature);
    }

    function isArray(o) {
        return Object.prototype.toString.call(o) == '[object Array]';
    }

    function gpsConvert(layer, features) {
        var isGcj02 = layer.get('isGcj02');
        if (isGcj02) {
            console.log("火星坐标地图，经纬度徐转换才能正确显示");
            //todo 转化要素坐标，加火星坐标标记
            toGcj02(features, 1);
        } else {
            console.log("标准坐标");
            //todo 转化要素坐标，加标准坐标标记
            toGcj02(features, 2);
        }
    }

    /**
     * 将地图上的要素进行坐标转换
     * @param features
     * @param type    1：to Gcj02;   2:to Gps84
     */
    function toGcj02(features, type) {
        if (isArray(features)) {
            for (var i = 0; i < features.length; i++) {
                toGcj02(features[i], type);
            }
        } else {
            var feature = features;
            var featureType = feature.get('gpsType');
            if (featureType == type) {
                return;
            }
            feature.set('gpsType', type);
            var geometry = feature.getGeometry();
            if (geometry == null) {
                return;
            }
            var geometryType = geometry.getType();
            var coordinates = geometry.getCoordinates();
            var newCoordinate,
                coordinate,
                newcoordinate = [],
                newCoordinates = [];
            switch (geometryType) {
                case 'LineString':
                    for (var i = 0; i < coordinates.length; i++) {
                        coordinate = coordinates[i];

                        var gps;
                        if (type == 1) {
                            gps = GPS.gcj_encrypt(coordinate[1], coordinate[0]);
                        } else if (type == 2) {
                            gps = GPS.gcj_decrypt_exact(coordinate[1], coordinate[0]);
                        }
                        newcoordinate = [gps.lon, gps.lat];

                        newCoordinates.push(newcoordinate);
                    }
                    geometry.setCoordinates(newCoordinates);
                    break;
                case 'Polygon':
                case 'MultiLineString':
                    for (var i = 0; i < coordinates.length; i++) {
                        coordinate = coordinates[i];
                        for (var j = 0; j < coordinate.length; j++) {
                            var gps;
                            if (type == 1) {
                                gps = GPS.gcj_encrypt(coordinate[j][1], coordinate[j][0]);
                            } else if (type == 2) {
                                gps = GPS.gcj_decrypt_exact(coordinate[j][1], coordinate[j][0]);
                            }
                            newcoordinate.push([gps.lon, gps.lat]);
                        }
                        newCoordinates.push(newcoordinate);
                    }
                    geometry.setCoordinates(newCoordinates);
                    break;
                case 'Point':
                    var gps;
                    if (type == 1) {
                        gps = GPS.gcj_encrypt(coordinates[1], coordinates[0]);
                    } else if (type == 2) {
                        gps = GPS.gcj_decrypt_exact(coordinates[1], coordinates[0]);
                    }
                    newcoordinate = [gps.lon, gps.lat];

                    geometry.setCoordinates(newcoordinate);
                    break;
            }

        }
    }

    /**
     * 获取当前图层
     * @returns {*}
     */
    function getCurrentLayer() {
        var layers = getLayers();
        for (var i = 0; i < layers.length; i++) {
            var visible = layers[i].get('visible');
            if (visible) {
                return layers[i];
            }
        }
    }

    var OverlayMap = {
        featureOverlay: featureOverlay,
        userPathOverlay: userPathOverlay,
        searchOverlay: searchOverlay
    };

    /**-------------------------------------全局变量-----------------------------------------*/
    window.map = map;
    window.features = features;
    window.userPathFeatures = userPathFeatures;
    window.searchFeatures = searchFeatures;
    window.featureOverlay = featureOverlay;
    window.userPathOverlay = userPathOverlay;
    window.searchOverlay = searchOverlay;
    window.view = view;
    window.updateFeatureStyle = updateFeatureStyle;
    window.updateContentStyle = updateContentStyle;
    window.addFeatures = addFeatures;
    window.addFeaturesToSearchOverlay = addFeaturesToSearchOverlay;
    window.removeFeatures = removeFeatures;
    window.isArray = isArray;
    window.getCurrentLayer = getCurrentLayer;
    window.gpsConvert = gpsConvert;
})
;
